package wyy

import (
	"api-go/cache"
	"api-go/serializer"
	"api-go/util"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	"github.com/go-redis/redis/v8"
)

// 歌单所需信息
type PlayList struct {
	Category string `form:"category"`
	Limit    string `form:"limit"`
	LastTime string `form:"updateTime"`
	Id       string `form:"id"`
}

//获取歌单列表
func (service *PlayList) PlaylistList() *serializer.Response {

	if val := service.Category; val != "" {
		service.Category = val
	} else {
		//全部,华语,欧美,韩语,日语,粤语,小语种,运动,ACG,影视原声,流行,摇滚,后摇,古风,民谣,轻音乐,电子,器乐,说唱,古典,爵士
		service.Category = "全部"
	}

	if val := service.Limit; val != "" {
		service.Limit = val
	} else {
		service.Limit = "20"
	}

	if val := service.LastTime; val != "" {
		service.LastTime = val
	} else {
		service.LastTime = "0"
	}

	service.Category = url.QueryEscape(service.Category)
	url := "https://music.163.com/api/playlist/highquality/list?total=true&cat=" + service.Category + "&limit=" + service.Limit + "&lasttime=" + service.LastTime
	res, err := util.Get(url)
	if err != nil {
		return err
	}
	return serializer.OkResponse(res)
}

//获取歌单信息
func (service *PlayList) PlaylistInfo() *serializer.Response {

	if val := service.Id; val != "" {
		service.Id = val
	} else {
		service.Id = "3136952023"
	}

	urlStr := "https://music.163.com/api/v6/playlist/detail?n=100000&s=8&id=" + service.Id
	res, err := util.WyyGet(urlStr)
	if err != nil {
		return err
	}

	//网易云歌单只能获取前20首音乐，故这里增加了根据歌曲id调用歌曲详情接口
	newRes := res.(map[string]interface{})["playlist"].(map[string]interface{})["trackIds"].([]interface{})
	var a []string
	out := []map[string]interface{}{}
	//拼接歌曲id，格式为[{id:111},{id:222}]
	//由于同时请求song/detail参数过多会请求失败，所有这里添加了设置超过250数据就分片
	for _, r := range newRes {
		// ress = ress + ",{id:" + strconv.FormatFloat(r.(map[string]interface{})["id"].(float64), 'f', -1, 64) + "}"
		a = append(a, ",{id:"+strconv.FormatFloat(r.(map[string]interface{})["id"].(float64), 'f', -1, 64)+"}")
	}
	//每隔250组数据分割一下
	// for i := 0; i <= len(a)/250; i++ {
	// 	var f int
	// 	if len(a) < 250 {
	// 		f = len(a)
	// 	} else if (len(a)-i*250)/250 < 1 {
	// 		f = len(a)%250 + i*250
	// 	} else {
	// 		f = (i + 1) * 250
	// 	}
	// 	var b = a[i*250 : f]
	// 	fmt.Println(len(b))
	// 	var d string
	// 	for _, c := range b {
	// 		d = d + c
	// 	}
	// 	// ress := strings.Replace(d, ",", "", 1)
	// 	d = "[" + d + "]"
	// 	d = strings.Replace(d, ",", "", 1)
	// 	url = "https://music.163.com/api/v3/song/detail?c=" + d
	// 	resss, err := util.Get(url)
	// 	if err != nil {
	// 		return err
	// 	}
	// 	//将数据也写入res中
	// 	aa := resss.(map[string]interface{})["songs"].([]interface{})
	// 	for _, v := range aa {
	// 		out = append(out, v.(map[string]interface{}))
	// 	}
	// }
	//使用post。不用分片，有效提高解析速度
	var d string
	for _, c := range a {
		d = d + c
	}
	d = "[" + d + "]"
	d = strings.Replace(d, ",", "", 1)
	urlStr = "https://music.163.com/api/v3/song/detail"
	client := &http.Client{}
	data := url.Values{}
	data.Set("c", d)
	r, _ := http.NewRequest("POST", urlStr, strings.NewReader(data.Encode())) // URL-encoded payload
	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	r.Header.Add("X-Forwarded-For", util.RandIp())
	resp, errs := client.Do(r)
	if errs != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	defer resp.Body.Close()
	datas, errs := ioutil.ReadAll(resp.Body)
	if errs != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	//赋值用于后面将string转为json
	bodyMapData := map[string]interface{}{}
	errs = json.Unmarshal(datas, &bodyMapData)
	if errs != nil {
		return serializer.ErrorResponse(serializer.CodeUnknownError)
	}
	//将数据也写入res中
	aa := bodyMapData["songs"].([]interface{})
	for _, v := range aa {
		out = append(out, v.(map[string]interface{}))
	}
	res.(map[string]interface{})["songs"] = out
	return serializer.OkResponse(res)
}

//获取歌单分类
func (service *PlayList) PlaylistCat() *serializer.Response {
	//定义redis key和判断redis是否有该值
	redisKey := "wyy-playlist-cat"
	redisResult, err := cache.RedisClient.Get(ctx, redisKey).Result()
	//若redis没有该值则执行获取
	if err == redis.Nil {
		url := "https://music.163.com/api/playlist/highquality/tags"
		res, err := util.Get(url)
		if err != nil {
			return err
		}
		//将结果转为Json数据
		b, e := json.Marshal(res)
		if e != nil {
			fmt.Println(err)
		}
		//转为string存入redis
		e = cache.RedisClient.Set(ctx, redisKey, string(b), 24*time.Hour).Err()
		if e != nil {
			fmt.Println("err1", err)
			return serializer.ErrorResponse(serializer.RedisError)
		}

		return serializer.OkResponse(res)
	} else if err != nil {
		fmt.Println("err2", err)
		return serializer.ErrorResponse(serializer.RedisError)
	} else {
		//将从redis获取的结果（string类型）转为map[string]inerface{}
		bodyMapData := map[string]interface{}{}
		err = json.Unmarshal([]byte(redisResult), &bodyMapData)
		if err != nil {
			fmt.Println("err3", err)
			return serializer.ErrorResponse(serializer.RedisError)
		}
		return serializer.OkResponse(bodyMapData)
	}
}

//获取推荐歌单
func (service *PlayList) PlaylistRecommend() *serializer.Response {
	if val := service.Limit; val != "" {
		service.Limit = val
	} else {
		service.Limit = "20"
	}

	//定义redis key和判断redis是否有该值
	redisKey := "wyy-playlist-recommend-" + service.Limit
	redisResult, err := cache.RedisClient.Get(ctx, redisKey).Result()
	//若redis没有该值则执行获取
	if err == redis.Nil {

		url := "https://music.163.com/api/personalized/playlist?total=true&n=1000&limit=" + service.Limit
		res, err := util.Get(url)
		if err != nil {
			return err
		}
		//将结果转为Json数据
		b, e := json.Marshal(res)
		if e != nil {
			fmt.Println(err)
		}
		//转为string存入redis
		e = cache.RedisClient.Set(ctx, redisKey, string(b), 24*time.Hour).Err()
		if e != nil {
			fmt.Println("err1", err)
			return serializer.ErrorResponse(serializer.RedisError)
		}

		return serializer.OkResponse(res)
	} else if err != nil {
		fmt.Println("err2", err)
		return serializer.ErrorResponse(serializer.RedisError)
	} else {
		//将从redis获取的结果（string类型）转为map[string]inerface{}
		bodyMapData := map[string]interface{}{}
		err = json.Unmarshal([]byte(redisResult), &bodyMapData)
		if err != nil {
			fmt.Println("err3", err)
			return serializer.ErrorResponse(serializer.RedisError)
		}
		return serializer.OkResponse(bodyMapData)
	}
}
